using CommunityToolkit.Mvvm.ComponentModel;
using HandyControl.Controls;
using Sensor.SerialPorts;
using Sensor.SerialPorts.Enums;
using Sensor.UI.Models;
using Sensor.UI.PointClouds;
using Sensor.UI.Processors;
using Sensor.UI.Protocols;
using Sensor.UI.Utils;
using System.Collections.Concurrent;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Channels;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows.Threading;
using MessageBox = HandyControl.Controls.MessageBox;

namespace Sensor.UI.ViewModels;

public partial class SerialSessionViewModel : ViewModelBase
{
    // 串口配置属性
    [ObservableProperty]
    private string _port = string.Empty;
    [ObservableProperty]
    private int _baudRate = 115200;
    [ObservableProperty]
    private ParityBit _parityBit = ParityBit.None;
    [ObservableProperty]
    private StopBit _stopBit = StopBit.One;
    [ObservableProperty]
    private int _dataBit = 8;

    // 状态属性
    [ObservableProperty]
    private bool _isOpen = false;

    //日志
    [ObservableProperty]
    private string _dataMessage = string.Empty;


    //点云
    [ObservableProperty]
    private PerspectiveCamera _pointCloudCamera = new();

    [ObservableProperty]
    private Point3DCollection _regionPoints = [];

    [ObservableProperty]
    private Point3DCollection _points = [];

    [ObservableProperty]
    private Model3DGroup _arrows = new();

    //数据
    private readonly SerialPortHandler _serialPortHandler = new();
    private readonly TextProtocolSplitter _splitter = new();
    private readonly DataProcessor _dataProcessor = new();

    // 消息队列相关
    private readonly DataMessageProcessor _dataMessageProcessor = new();

    //点云
    private readonly SensorProcessor _sensorProcessor = new();
    private readonly PointCloudInfo pointCloudInfo = PointCloudFactory.LoadModel(10, 20, 10, 100, 100, 4);
    
    // 高性能组件
    private readonly HighSpeedDataProcessor _highSpeedDataProcessor;
    private readonly AsyncUIUpdater _asyncUIUpdater;
    private readonly DataFlowController _dataFlowController;
    private readonly AdvancedPerformanceMonitor _performanceMonitor;

    public SerialSessionViewModel()
    {
        // 初始化高性能组件
        _highSpeedDataProcessor = new HighSpeedDataProcessor();
        _asyncUIUpdater = new AsyncUIUpdater(updateIntervalMs: 16); // 约60FPS
        _dataFlowController = new DataFlowController(capacity: 10000);
        _performanceMonitor = new AdvancedPerformanceMonitor();

        // 设置高性能数据处理事件处理
        _highSpeedDataProcessor.OnDataReady += async (data) =>
        {
            // 通过数据流控制器处理数据
            if (_dataFlowController.TryAdd(Encoding.UTF8.GetBytes(data)))
            {
                // 数据已成功添加到流控制器
                await _performanceMonitor.RecordDataProcessedAsync(data.Length);
            }
            else
            {
                // 数据丢失，记录统计
                await _performanceMonitor.RecordDataLossAsync(data.Length);
            }
        };

        // 设置数据流控制器处理回调
        _dataFlowController.SetProcessingCallback(async (data, token) =>
        {
            // 处理数据并更新UI
            await ProcessHighSpeedDataAsync(data, token);
        });

        // 设置异步UI更新回调
        _asyncUIUpdater.SetUpdateCallback(async (data, token) =>
        {
            // 更新UI文本框
            await UpdateUITextBoxAsync(data, token);
        });

        // 启动性能监控
        _ = Task.Run(async () => await _performanceMonitor.StartMonitoringAsync());

        PointCloudCamera.Position = pointCloudInfo.CameraInfo.Position;
        PointCloudCamera.LookDirection = pointCloudInfo.CameraInfo.LookDirection;
        PointCloudCamera.UpDirection = pointCloudInfo.CameraInfo.UpDirection;

        // 构造函数在 UI 线程上执行，可以直接调用 LoadPointCloud
        LoadPointCloud();
    }


    public async Task<bool> OpenAsync()
    {
        if (IsOpen)
        {
            return true;
        }

        try
        {
            // 初始化状态
            ClearDataReceived();
            _splitter.Reset();

            // 启动高性能数据处理组件
            _asyncUIUpdater.Start();
            _dataFlowController.Start();

            // 启动处理线程
            _dataMessageProcessor.OnProcessAsync += OnDataMessageProcessAsync;
            _dataMessageProcessor.Start();

            _dataProcessor.OnProcessAsync += OnDataProcessAsync;
            _dataProcessor.Start();

            _sensorProcessor.OnProcessAsync += OnSensorProcessAsync;
            _sensorProcessor.Start();
            
            // 注册事件处理器
            _serialPortHandler.OnData += OnData;
            _serialPortHandler.OnException += OnException;

            // 打开串口
            bool result = _serialPortHandler.Open(Port, BaudRate, ParityBit, StopBit, DataBit);
            IsOpen = result;
            
            if (result)
            {
                AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 串口已打开: {Port} @ {BaudRate}");
            }
            
            return result;
        }
        catch (Exception ex)
        {
            AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 打开串口失败: {ex.Message}");
            IsOpen = false;
            return false;
        }
    }

  

    public async Task CloseAsync()
    {
        if (!IsOpen)
        {
            return;
        }

        try
        {
            // 停止高性能数据处理组件
            _asyncUIUpdater.Stop();
            _dataFlowController.Stop();

            // 停止处理线程
            _dataMessageProcessor.OnProcessAsync -= OnDataMessageProcessAsync;
            _dataMessageProcessor.Stop();

            _dataProcessor.OnProcessAsync -= OnDataProcessAsync;
            _dataProcessor.Stop();

            _sensorProcessor.OnProcessAsync -= OnSensorProcessAsync;
            _sensorProcessor.Stop();

            // 先移除事件处理器，再关闭串口
            _serialPortHandler.OnData -= OnData;
            _serialPortHandler.OnException -= OnException;

            // 关闭串口
            await _serialPortHandler.CloseAsync();

            IsOpen = false;
            AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 串口已关闭");
        }
        catch (Exception ex)
        {
            AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 关闭串口失败: {ex.Message}");
        }
    }



    /// <summary>
    /// 清空接收数据
    /// </summary>
    public void ClearDataReceived()
    {
        DataMessage = string.Empty;
    }


    #region 数据接受
    private async void OnData(byte[] data)
    {
        // 使用高性能处理器处理数据
        if (_highSpeedDataProcessor != null)
        {
            // 直接传递字节数据，由处理器内部进行转换
            _highSpeedDataProcessor.AddData(data);
        }

        // 保留传统处理逻辑作为备用
        if (_dataProcessor != null)
        {
            try
            {
                _dataProcessor.Add(data);
            }
            catch (Exception ex)
            {
                AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 数据处理错误: {ex.Message}");
            }
        }

        // 更新性能统计
        if (_performanceMonitor != null)
        {
            _performanceMonitor.RecordDataReceived(data.Length);
        }
    }

    /// <summary>
    /// 高速数据处理方法
    /// </summary>
    private async Task ProcessHighSpeedDataAsync(byte[] data, CancellationToken token)
    {
        try
        {
            // 将字节数据转换为字符串用于显示
            string dataString = Encoding.UTF8.GetString(data);
            
            // 将数据添加到异步UI更新器
            _asyncUIUpdater.AddData(dataString);
            
            // 记录处理统计
            await _performanceMonitor.RecordDataProcessedAsync(data.Length, token);
        }
        catch (Exception ex)
        {
            AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 高速数据处理异常: {ex.Message}");
        }
    }

    /// <summary>
    /// 异步更新UI文本框
    /// </summary>
    private async Task UpdateUITextBoxAsync(string data, CancellationToken token)
    {
        try
        {
            // 使用Dispatcher在UI线程上更新文本框
            await Application.Current.Dispatcher.InvokeAsync(() =>
            {
                // 检查数据消息长度，避免过长
                if (_dataMessageBuilder.Length > 50000)
                {
                    _dataMessageBuilder.Clear();
                    _dataMessageBuilder.AppendLine("数据清空");
                }

                _dataMessageBuilder.AppendLine(data);
                DataMessage = _dataMessageBuilder.ToString();
            }, DispatcherPriority.Background, token);
        }
        catch (Exception ex)
        {
            AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# UI更新异常: {ex.Message}");
        }
    }

    private void OnException(Exception ex)
    {
        AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 串口异常: {ex.Message}  ");
    }

    private Task OnDataProcessAsync(byte[] data, CancellationToken token)
    {
        token.ThrowIfCancellationRequested();
        try
        {
            var protocolDatas = _splitter.Process(data);
            foreach (var protocolData in protocolDatas)
            {
                AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 数据接: {protocolData}   ");
                
                // 解析协议数据为SensorInfo
                var sensorInfo = TestProtocolSensorConverter.Process(protocolData);
                if (sensorInfo != null)
                {
                    // 更新点云数据
                    AddSensor(sensorInfo);
                }
                else {
                    AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 数据格式解析出错: {protocolData}");
                }
            }
        }
        catch (Exception ex)
        {
            AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 数据接收错误: {ex.Message}  ");
        }

        return Task.CompletedTask;
    }
    
    #endregion


    #region 记录消息
    /// <summary>
    /// 添加消息到队列
    /// </summary>
    private void AddMessage(string message)
    {
        _dataMessageProcessor.Add(message);
    }

    private Task OnDataMessageProcessAsync(string data, CancellationToken token)
    {
        token.ThrowIfCancellationRequested();
        try
        {
            // 使用 Dispatcher 将 UI 更新操作调度到 UI 线程
            Application.Current.Dispatcher.Invoke(() => DataMessage = data);
        }
        catch (Exception ex)
        {
            MessageBox.Error(ex.Message);
        }
        return Task.CompletedTask;
    }


    #endregion


    #region 点云
    /// <summary>
    /// 添加消息到队列
    /// </summary>
    private void AddSensor(SensorInfo data)
    {
        _sensorProcessor.Add(data);
    }

    private Task OnSensorProcessAsync(SensorInfo? data, CancellationToken token)
    {
        token.ThrowIfCancellationRequested();
        try
        {
            // 使用 Dispatcher 将 UI 更新操作调度到 UI 线程
            Application.Current.Dispatcher.Invoke(() => UpdatePointCloud(data));
        }
        catch (Exception ex)
        {
            AddMessage($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]# 刷新点云: {ex.Message}  ");
        }
        return Task.CompletedTask;
    }

    private void LoadPointCloud()
    {
        Points.Clear();

        RegionPoints.Clear();
        Arrows.Children.Clear();

        List<Point3D> newRegionPoints = [];
        List<Point3D> newPoints = [];

        foreach (var itemInfo in pointCloudInfo.ItemInfos)
        {
            newPoints.Add(itemInfo.Point);
        }

        foreach (var regionInfo in pointCloudInfo.RegionInfos)
        {
            foreach (var itemInfo in regionInfo.ItemInfos)
            {
                newRegionPoints.Add(itemInfo.Point);
            }
        }

        RegionPoints = [.. newRegionPoints];
        Points = [.. newPoints];
    }

    private void UpdatePointCloud(SensorInfo? sensorInfo)
    {
        // 如果sensorInfo为null，直接从pointCloudInfo刷新点云
        if (sensorInfo == null)
        {
            LoadPointCloud();
            return;
        }

        RegionPoints.Clear();
        Arrows.Children.Clear();

        double maxLength = Math.Sqrt(10 * 10 + 10 * 10); // 最大可能长度（当X和Y都为最大值10时）

        var arrowGroup = new Model3DGroup();

        foreach (var regionInfo in pointCloudInfo.RegionInfos)
        {
            SensorItemInfo? sensorItemInfo = sensorInfo.SensorItemInfos.FirstOrDefault(a => a.Index == regionInfo.Index);
            if (sensorItemInfo != null)
            {
                #region 箭头
                // 计算箭头长度：sqrt(x^2 + y^2)
                double rawLength = Math.Sqrt(sensorItemInfo.X * sensorItemInfo.X + sensorItemInfo.Y * sensorItemInfo.Y);

                // 归一化缩放箭头长度，使其在合理范围内（0.5到3.0之间）
                double normalizedLength = 0.5 + (rawLength / maxLength) * 2.5; // 归一化到0.5-3.0范围

                // 获取区域的法向量
                Vector3D normalVector = regionInfo.CenterItemInfo.Vector;

                // 创建与法向量垂直的箭头方向向量
                Vector3D arrowDirection;

                // 如果法向量接近Y轴，使用X轴作为参考
                if (Math.Abs(normalVector.Y) > 0.9)
                {
                    arrowDirection = new Vector3D(0, 0, 1);
                }
                else
                {
                    arrowDirection = new Vector3D(0, 1, 0);
                }

                // 计算与法向量垂直的方向向量
                arrowDirection = Vector3D.CrossProduct(normalVector, arrowDirection);
                arrowDirection.Normalize();

                // 根据传感器数据调整箭头方向
                double angle = Math.Atan2(sensorItemInfo.X, sensorItemInfo.Y);

                // 创建旋转矩阵，绕法向量旋转
                var rotationAxis = normalVector;
                var rotationAngle = angle;

                // 应用旋转到箭头方向
                var cosAngle = Math.Cos(rotationAngle);
                var sinAngle = Math.Sin(rotationAngle);
                var oneMinusCos = 1.0 - cosAngle;

                var x = rotationAxis.X;
                var y = rotationAxis.Y;
                var z = rotationAxis.Z;

                // 罗德里格斯旋转公式
                Vector3D rotatedDirection = new (
                    (cosAngle + x * x * oneMinusCos) * arrowDirection.X +
                    (x * y * oneMinusCos - z * sinAngle) * arrowDirection.Y +
                    (x * z * oneMinusCos + y * sinAngle) * arrowDirection.Z,
                    (y * x * oneMinusCos + z * sinAngle) * arrowDirection.X +
                    (cosAngle + y * y * oneMinusCos) * arrowDirection.Y +
                    (y * z * oneMinusCos - x * sinAngle) * arrowDirection.Z,
                    (z * x * oneMinusCos - y * sinAngle) * arrowDirection.X +
                    (z * y * oneMinusCos + x * sinAngle) * arrowDirection.Y +
                    (cosAngle + z * z * oneMinusCos) * arrowDirection.Z
                );

                // 使用区域中心点作为箭头起点，创建箭头模型
                var arrow = ArrowFactory.CreateArrow(
                    regionInfo.CenterPoint,
                    rotatedDirection,
                    normalizedLength
                );

                arrowGroup.Children.Add(arrow);
                #endregion

                #region 力场凹陷
                // 对区域内的每个点应用力场凹陷效果
                foreach (var itemInfo in regionInfo.ItemInfos)
                {
                    // 计算点到区域中心的距离
                    double distanceToCenter = itemInfo.DistanceToCenter;
                    
                    // 获取传感器数据的Z坐标，代表力的大小
                    // Z值为正表示向下的力，Z值为负表示向上的力
                    double zForce = sensorItemInfo.Z;
                    
                    // 归一化Z力到[0,1]范围，25.0是传感器Z坐标的最大值
                    // 使用绝对值，因为我们关心的是力的大小而不是方向
                    double zForceNormalized = Math.Abs(zForce) / 25.0;
                    
                    // 计算距离衰减因子：距离越大，力的影响越小
                    // 使用更平缓的高斯函数实现平滑的距离衰减
                    double distanceAttenuation = Math.Exp(-2.0 * Math.Pow(distanceToCenter / regionInfo.DistanceThreshold, 1.5));
                    distanceAttenuation = Math.Max(0, Math.Min(1, distanceAttenuation)); // 限制在[0,1]范围内
                    
                    // 计算力的方向：Z值为正表示向下凹陷，Z值为负表示向上凸起
                    double forceDirection = Math.Sign(zForce);
                    
                    // 综合Z力大小和距离衰减，计算最终凹陷强度
                    // 使用平方根函数使力的影响更加平滑
                    double finalInfluence = Math.Sqrt(zForceNormalized) * distanceAttenuation;
                    
                    // 使用点自身的法向量（Vector属性）作为变形方向
                    // 根据力的方向决定是凹陷还是凸起
                    Vector3D deformationDirection = forceDirection > 0 ? -itemInfo.Vector : itemInfo.Vector;
                    deformationDirection.Normalize();
                    
                    // 计算变形偏移量（强度乘以方向）
                    double maxDeformation = 4.0; // 减小最大变形深度，使变化更平滑
                    Vector3D deformationOffset = deformationDirection * (finalInfluence * maxDeformation);
                    
                    // 应用变形效果，创建新的点位置
                    Point3D deformedPoint = new(
                        itemInfo.Point.X + deformationOffset.X,
                        itemInfo.Point.Y + deformationOffset.Y,
                        itemInfo.Point.Z + deformationOffset.Z
                    );

                    // 添加到RegionPoints
                    RegionPoints.Add(deformedPoint);
                }
                #endregion
            }
            else
            {
                // 如果没有对应的传感器数据，使用原始点位置
                foreach (var itemInfo in regionInfo.ItemInfos)
                {
                    RegionPoints.Add(itemInfo.Point);
                }
            }
        }

        // 更新箭头模型
        Arrows = arrowGroup;
    }

    #endregion

    #region 资源释放
    private bool _disposedValue = false;

    /// <summary>
    /// 释放资源
    /// </summary>
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposedValue)
        {
            if (disposing)
            {
                // 停止所有处理器
                _highSpeedDataProcessor?.Dispose();
                _asyncUIUpdater?.Dispose();
                _dataFlowController?.Dispose();
                _performanceMonitor?.Dispose();

                // 停止传统处理器
                _dataMessageProcessor?.Dispose();
                _dataProcessor?.Dispose();
                _sensorProcessor?.Dispose();

                // 关闭串口
                _serialPortHandler?.Dispose();
            }

            _disposedValue = true;
        }
    }

    /// <summary>
    /// 析构函数
    /// </summary>
    ~SerialSessionViewModel()
    {
        Dispose(false);
    }

    /// <summary>
    /// 实现IDisposable接口
    /// </summary>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion
}
